using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml;
using DynamiteXml;

namespace DynamiteXml.HelperLogic
{
    /// <summary>
    /// This class (de)serializes an xml serializable object.
    /// Used internally by the DynamiteXmlSerializeLogic
    /// </summary>
    public class Serializer : IXmlSerializable
    {
        /// <summary>
        /// Default constructor required for serialization.
        /// </summary>
        public Serializer()
        {
            // Intentionally left empty.
        }        

        /// <summary>
        /// Constructor that accepts the object that is to be serialized / deserialized by the DynamiteXmlSerializer.
        /// </summary>
        /// <param name="DynamiteXml">
        /// The object that is to be serialized / deserialized
        /// It needs to implement the IDynamiteXml naming interface.
        /// </param>
        public Serializer(IDynamiteXml DynamiteXml)
        {
            this.dynamiteXml = DynamiteXml;
        }

        /// <summary>
        /// The object that is to be serialized / deserialized. Readonly.
        /// </summary>
        public IDynamiteXml DynamiteXml
        {
            get
            {
                return dynamiteXml;
            }
        }

        private IDynamiteXml dynamiteXml;

        private string rawXml;
        /// <summary>
        /// The IDynamiteXml represented as raw xml string. 
        /// </summary>
        public string RawXml
        {
            get { return rawXml; }
            set { rawXml = value; }
        }

        #region IXmlSerializable Members
        /// <summary>
        /// The schema required by ancester IXmlSerializable.
        /// For DynamiteXmlSerializer, it will always be null.
        /// </summary>
        /// <returns></returns>
        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// This method fills the RawXml property.
        /// Implementation is required by IXmlSerializable for deserialization.
        /// </summary>
        /// <param name="reader"></param>
        public void ReadXml(XmlReader reader)
        {
            RawXml = reader.ReadInnerXml();
        }

        /// <summary>
        /// Generates the xml from the IDynamiteXml.
        /// Implementation is required by IXmlSerializable for serialization.
        /// </summary>
        /// <param name="writer"></param>
        public void WriteXml(XmlWriter writer)
        {
            StringBuilder xmlStringBuilder = new StringBuilder();
            using (XmlWriter dynamiteXmlWriter = XmlWriter.Create(xmlStringBuilder))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(DynamiteXml.GetType());
                xmlSerializer.Serialize(dynamiteXmlWriter, DynamiteXml);
            }
            string xmlString = xmlStringBuilder.ToString();

            xmlString = xmlString.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
            writer.WriteRaw(xmlString);
        }
        #endregion
    }
}
